/*
 * 文件名： AlipayScanPayCmbcManager.java
 * 
 * 工程名称: bis-manager
 *
 * Gopay
 *
 * 创建日期： 2017年1月11日
 *
 * Copyright(C) 2017, by www.gopay.com.cn Inc.All rights reserved.
 *
 * 原始作者: 宣广海
 *
 */
package com.gopay.bis.manager.bank.scan;

import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.gopay.common.constants.bank.CmbcConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.ScanPayBaseMessage;
import com.gopay.common.domain.bank.alipay.cmbc.AlipayHead;
import com.gopay.common.domain.bank.alipay.cmbc.AlipayTransMsg;
import com.gopay.common.domain.bank.alipay.cmbc.scan.AlipayQueryBody;
import com.gopay.common.domain.bank.alipay.cmbc.scan.AlipayRefundBody;
import com.gopay.common.domain.bank.alipay.cmbc.scan.AlipayScanPayBody;
import com.gopay.common.domain.cust.CustSettledInfo;
import com.gopay.common.exception.GopayException;
import com.gopay.common.user.dao.CustSettledInfoDao;
import com.gopay.remote.bank.businesses.CmbcScanPayService;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * 支付宝扫码民生渠道报文拼装处理
 *
 * @author 宣广海
 *
 * @version
 *
 * @since 2017年1月11日
 */
public class AlipayScanPayCmbcManager {
	/**
	 * 日志对象
	 */
	private static Logger logger = LoggerFactory.getLogger(AlipayScanPayCmbcManager.class);
	/**
	 * 注入对象
	 */
	@Resource(name = "alipayScanPayCmbcServiceClient")
	private CmbcScanPayService alipayScanPayCmbcServiceClient;
		
    @Resource(name = "alipayScanPayConfig")
    private Map<String,String> alipayScanPayConfig;
    
	@Resource(name = "custSettledInfoDao")
	private CustSettledInfoDao custSettledInfoDao;

	/**
	 * 
	 * 功能描述：支付宝支付民生渠道支付报文
	 *
	 * @param msg
	 * @return
	 * @throws GopayException
	 * 
	 * @author 宣广海
	 *
	 * @since 2017年1月11日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public Object scanPay(BaseMessage msg) throws GopayException {
		AlipayTransMsg<AlipayScanPayBody> message = new AlipayTransMsg<AlipayScanPayBody>();
		msg.setBankOrderId(modifyOrderId(msg.getOrderId()));
		try {
			BeanUtils.copyProperties(msg, message);
			/**
			 * 获取商户入驻编号
			 */
			CustSettledInfo info = custSettledInfoDao.getCustSettledInfo(msg.getCustomerID(),
					CmbcConstants.ZFB_SETTLED, CmbcConstants.ZFB_SETTLED_SUCCESS);
			if (null == info) {
				logger.info(msg.getCustomerID() + ",此商户没有找到支付宝入驻帐号！");
				throw new GopayException(ProcCodeConstants.PROC_CODE_100E1165);
			}
			/**
			 * 准备构建报文体对象
			 */
			ScanPayBaseMessage scanPayBase = (ScanPayBaseMessage) msg;
			AlipayScanPayBody alipayScanPayBody = new AlipayScanPayBody();
			alipayScanPayBody.setMerchantCode(info.getBankMerchantCode());
			/**
			 * 金额精确到元，保留2位小数
			 */
			alipayScanPayBody.setTotalAmount(scanPayBase.getAmount());
			alipayScanPayBody.setSubject(scanPayBase.getGoodsBody());
			alipayScanPayBody.setDesc(scanPayBase.getGoodsBody());
			alipayScanPayBody.setOperatorId("");
			alipayScanPayBody.setStoreId("");
			alipayScanPayBody.setTerminalId("");
			// 1-限定不能使用信用卡支付
			alipayScanPayBody.setLimitPay("1");
			alipayScanPayBody.setSource("");
			/**
			 * 订单失效时间目前是6分钟后失效
			 * 指定订单的支付有效时间（分钟数），超过有效时间用户将无法支付。若不指定该参数则系统默认设置24小时支付有效时间。参数允许设置范围：
			 * 1-1440区间的整数值，超过1440默认设置1440
			 */
			alipayScanPayBody.setExpireTime(6);
			
			message.setHead(creatHead());
			message.setBody(alipayScanPayBody);
			message.setPlainMessage(buildSignPlain(message));
			logger.info("alipay pay manager sign message :" + buildSignPlain(message));
		} catch (Exception e) {
			logger.info(e.getMessage());
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E7025, e);
		}
		return	alipayScanPayCmbcServiceClient.payment(message);
	}
	/**
	 * 
	 * 功能描述：支付宝支付民生渠道订单查询报文
	 *
	 * @param msg
	 * @return
	 * @throws GopayException
	 * 
	 * @author 宣广海
	 *
	 * @since 2017年1月12日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public Object orderQuery(BaseMessage msg) throws GopayException {
		AlipayTransMsg<AlipayQueryBody> message = new AlipayTransMsg<AlipayQueryBody>();		
		try {
			BeanUtils.copyProperties(msg, message);	
			/**
			 * 准备构建报文体对象
			 */
			AlipayQueryBody queryBody = new AlipayQueryBody();		
			queryBody.setOriReqMsgId(msg.getBankOrderId());	//原订单号
			queryBody.setOperatorId("");
			message.setHead(creatHead());
			message.setBody(queryBody);
			message.setPlainMessage(buildSignPlain(message));
			logger.info("alipay query manager orderQuery message :" + buildSignPlain(message));
		} catch (Exception e) {
			logger.info(e.getMessage());
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6063, e);
		}
		return	alipayScanPayCmbcServiceClient.queryOrder(message);
	}
	/**
	 * 
	 * 功能描述：支付宝支付民生渠道退款报文
	 *
	 * @param msg
	 * @return
	 * @throws GopayException
	 * 
	 * @author 宣广海
	 *
	 * @since 2017年1月13日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public Object refund(BaseMessage msg) throws GopayException {
		AlipayTransMsg<AlipayRefundBody> message = new AlipayTransMsg<AlipayRefundBody>();
		msg.setBankOrderId(modifyOrderId(msg.getOrderId()));
		try {
			BeanUtils.copyProperties(msg, message);
			/**
			 * 准备构建报文体对象
			 */
			AlipayRefundBody alipayRefundBody = new AlipayRefundBody();
			/**
			 * 原支付交易流水号
			 */
			alipayRefundBody.setOriReqMsgId(msg.getTkOriBankOrderId());
			/**
			 * 退款金额精确到元，保留2位小数
			 */
			alipayRefundBody.setRefundAmount(msg.getAmount());
			alipayRefundBody.setRefundReason("");
			alipayRefundBody.setOperatorId("");
			alipayRefundBody.setStoreId("");
			alipayRefundBody.setTerminalId("");
			
			message.setHead(creatHead());
			message.setBody(alipayRefundBody);
			message.setPlainMessage(buildSignPlain(message));
			logger.info("alipay  refund manager sign message :" + buildSignPlain(message));
		} catch (Exception e) {
			logger.info(e.getMessage());
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E1163, e);
		}
		return	alipayScanPayCmbcServiceClient.refund(message);
	}
	/**
	 * 
	 * 功能描述：支付宝支付民生渠道异步通知验签
	 *
	 * @param msg
	 * @return
	 * @throws GopayException
	 * 
	 * @author 宣广海
	 *
	 * @since 2017年1月13日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public Object verify(BaseMessage msg) throws GopayException {
		boolean falg = false;
		try {
			logger.info("aplipay  manager verify message :" + ToStringBuilder.reflectionToString(msg));
			falg = (boolean) alipayScanPayCmbcServiceClient.verify(msg);
		} catch (Exception e) {
			logger.info(e.getMessage());
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E7026, e);
		}
		return falg;
	}
	/**
	 * 
	 * 功能描述：上送银行订单号加前缀
	 *
	 * @param orderId
	 * @return
	 * 
	 * @author 宣广海
	 *
	 * @since 2017年1月11日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	private static String modifyOrderId(String orderId) {

		return "MS" + orderId.substring(2);

	}
	/**
	 * 
	 * 功能描述：公共请求报文头
	 *
	 * @return
	 * 
	 * @author 宣广海
	 *
	 * @since 2017年1月12日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public AlipayHead creatHead() {
		AlipayHead head = new AlipayHead();
		head.setVersion(alipayScanPayConfig.get("ALIPAY.SCANPAY.VERSION"));
		head.setMsgType(alipayScanPayConfig.get("ALIPAY.SCANPAY.MESSAGETYPE"));
		head.setReqDate(new DateTime().toString("yyyyMMddHHmmss"));
		return head;
	}
	/**
	 * 
	 * 功能描述：
	 *
	 * @param obj
	 * @param bodyCla
	 * @return
	 * 
	 * @author 宣广海
	 *
	 * @since 2017年1月12日
	 *
	 * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
	 */
	public String buildSignPlain(Object obj) {
		// 去掉多一个下划线的问题
		XStream xstream = new XStream(new DomDriver("UTF-8", new NoNameCoder()));
		xstream.processAnnotations(obj.getClass());
		return xstream.toXML(obj);
	}
}
